import asyncio
import logging

from config import socket_ip, socket_port, open_mock_socket, mock_socket_ip

queue_send_to_server = None

connect_flag = False

q_recv_data = None

event_connect_start = None

event_socket_connected = None

event_open_cmd_send = None

window_width = 20

current_processing_arr = []
logger = logging.getLogger("uvicorn")


def socket_client_start(send_to_server_queue, q_recv_data1, event_connect_start1, event_socket_connected1,
                        event_open_cmd_send1):
    print('socket client start')
    global queue_send_to_server
    global q_recv_data
    global event_connect_start
    global event_socket_connected
    global event_open_cmd_send
    event_connect_start = event_connect_start1
    queue_send_to_server = send_to_server_queue
    event_socket_connected = event_socket_connected1
    q_recv_data = q_recv_data1
    event_open_cmd_send = event_open_cmd_send1
    asyncio.run(start())


async def start():
    while True:
        await connect_to_server()
        # print('1秒后开始重连')
        await asyncio.sleep(1)


async def connect_to_server():
    global q_recv_data
    global event_connect_start
    global event_open_cmd_send
    try:
        ip = mock_socket_ip if open_mock_socket else socket_ip
        reader, writer = await asyncio.open_connection(ip, socket_port)
        event_socket_connected.set()
        # 连接成功直接发出启动命令
        # queue_send_to_server.put(bytes(list([0x00, 0x01, 0x00, 0x00])))
        # print('发出开启命令')
        print('socket 连接成功')
    except Exception:
        event_socket_connected.clear()
        # print('没有连接上')
        return
    while True:
        try:
            # 接收服务器发送的数据
            # 发送数据到服务器
            if queue_send_to_server.qsize() > 0:
                msg = queue_send_to_server.get()
                writer.write(msg)
                await writer.drain()
            else:
                writer.write(int.to_bytes(1))
                await writer.drain()
            try:
                task = asyncio.create_task(reader.read(40))
                data = await asyncio.wait_for(task, 1)
                print(f'receive socket data: {data}')
                event_open_cmd_send.set()
                if event_connect_start.is_set():
                    arr = map_receive_data(list(bytes(data)))
                    handle_data(arr)
                else:
                    while q_recv_data.qsize() > 0:
                        q_recv_data.get()
            except asyncio.TimeoutError:
                event_open_cmd_send.clear()
                # print("socket client: wait for socket server msg timeout, retrying")
        except Exception as e:
            event_socket_connected.clear()
            event_open_cmd_send.clear()
            print("与socket服务器的连接断开")
            print(e)
            break


def map_receive_data(list):
    data_count = int(len(list) / 4)
    arr = []
    for index in range(data_count):
        val = list[index * 4 + 2] * 256 + list[index * 4 + 3]
        if val <= 2:
            continue
        arr.append(val)
    return arr


def smooth_filter_raw_data(arr):
    global current_processing_arr
    if len(current_processing_arr) + len(arr) < window_width:
        current_processing_arr = current_processing_arr + arr
        return arr
    else:
        smooth_arr = []
        pre_total = sum(current_processing_arr)
        for each in arr:
            current_processing_arr.append(each)
            pre_total = pre_total - current_processing_arr[0] + each
            smooth_data = int(pre_total / (len(current_processing_arr) - 1))
            smooth_arr.append(smooth_data)
            current_processing_arr = current_processing_arr[1:]
        return smooth_arr


def handle_data(arr):
    q_recv_data.put(arr)
